<template>
  <div>
    <el-tabs
      v-if="!formVisible"
      type="border-card"
      v-model="showTab"
      @tab-click="tabClick"
    >
      <el-tab-pane name="functions" label="功能列表">
        <el-table
          size="small"
          :data="functions"
          highlight-current-row
          v-loading="$store.state.loading"
          border
          element-loading-text="拼命加载中"
          style="width: 100%"
        >
          <el-table-column sortable prop="type" label="功能类型" width="100">
          </el-table-column>
          <el-table-column sortable prop="name" label="功能名称" width="180">
          </el-table-column>
          <el-table-column
            sortable
            prop="identifier"
            label="标识符"
            width="150"
          >
          </el-table-column>
          <el-table-column
            sortable
            prop="dataTypeName"
            label="数据类型"
            width="100"
          >
          </el-table-column>
          <el-table-column sortable prop="params" label="数据定义" width="200">
          </el-table-column>
          <el-table-column align="center" min-width="100">
            <template slot="header">
              <el-button @click="addFunction()" type="primary" size="mini" plain
                >新增功能</el-button
              >
            </template>
            <template slot-scope="scope">
              <el-button
                size="mini"
                @click="handleEdit(scope.$index, scope.row)"
                >编辑</el-button
              >
              <el-popconfirm
                title="确认要删除该功能吗？"
                @confirm="deleteFunction(scope.$index, scope.row)"
                class="mg-left-10"
              >
                <el-button slot="reference" size="mini" plain type="danger"
                  >删除</el-button
                >
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>
      <el-tab-pane name="tsl" label="TSL">
        <el-form>
          <vue-json-editor
            v-model="model"
            :showBtns="false"
            :mode="'code'"
            lang="zh"
          />
        </el-form>
      </el-tab-pane>

      <el-tab-pane name="script" label="型号配置">
        <div v-if="!productModelFormVisible">
          <div class="mg-bottom-10">
            <el-button size="mini" plain @click="addProductModel()"
              >新增</el-button
            >
          </div>
          <el-table
            size="small"
            :data="productModels"
            highlight-current-row
            v-loading="$store.state.loading"
            border
            element-loading-text="拼命加载中"
            style="width: 100%"
          >
            <el-table-column sortable prop="model" label="型号" width="150">
            </el-table-column>
            <el-table-column sortable prop="name" label="名称" width="150">
            </el-table-column>
            <el-table-column sortable prop="state" label="脚本状态" width="100">
            </el-table-column>
            <el-table-column
              sortable
              prop="modifyAt"
              label="修改时间"
              width="200"
            >
              <template slot-scope="scope">
                <div>{{ scope.row.modifyAt | timestampToTime }}</div>
              </template>
            </el-table-column>
            <el-table-column align="center" min-width="200">
              <template slot-scope="scope">
                <el-button
                  @click="modifyProductModel(scope.row)"
                  type="primary"
                  size="mini"
                  plain
                  >修改</el-button
                >
                <el-popconfirm
                  title="确认要删除该型号吗？"
                  @confirm="deleteProductModel(scope.row)"
                  class="mg-left-10"
                >
                  <el-button slot="reference" size="mini" plain type="danger"
                    >删除</el-button
                  >
                </el-popconfirm>
              </template>
            </el-table-column>
          </el-table>
        </div>

        <el-form
          v-else
          ref="productModelForm"
          :model="productModelForm"
          :rules="scriptRules"
          label-width="80px"
        >
          <el-form-item label="型号" style="width: 300px" prop="model">
            <el-input v-model="productModelForm.model" size="mini"></el-input>
          </el-form-item>
          <el-form-item label="型号名称" style="width: 300px" prop="name">
            <el-input v-model="productModelForm.name" size="mini"></el-input>
          </el-form-item>
          <el-form-item label="状态" prop="state">
            <el-radio-group v-model="productModelForm.state" size="mini">
              <el-radio label="dev">开发</el-radio>
              <el-radio label="publish">发布</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="Lua脚本" prop="script" class="product-script">
            <LuaScriptEditor :code="productModelForm"></LuaScriptEditor>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" size="small" @click="saveProductModel()"
              >保存</el-button
            >
            <el-button size="small" @click="cancelProductModel()"
              >取消</el-button
            >
          </el-form-item>
        </el-form>
      </el-tab-pane>
    </el-tabs>

    <el-tabs v-if="formVisible" type="border-card" value="functionModify">
      <el-tab-pane
        name="functionModify"
        :label="isAdd ? '添加功能' : '修改功能'"
      >
        <el-form
          class="model-form"
          label-width="120px"
          :model="modelForm"
          ref="modelForm"
        >
          <el-form-item label="功能类型">
            <el-radio-group
              :disabled="!isAdd"
              v-model="modelForm.type"
              size="mini"
            >
              <el-radio-button label="property">属性</el-radio-button>
              <el-radio-button label="service">服务</el-radio-button>
              <el-radio-button label="event">事件</el-radio-button>
            </el-radio-group>
          </el-form-item>
          <div v-if="isSelectType('property')">
            <PropertyModel
              :property="modelForm.raw"
              :enumItems="enumItems"
              :boolItem="boolItem"
              :isProperty="true"
            ></PropertyModel>
          </div>
          <div v-if="isSelectType('service')">
            <div>
              <el-form-item label="名称" prop="name">
                <el-input
                  v-model="modelForm.name"
                  size="small"
                  auto-complete="off"
                ></el-input>
              </el-form-item>
              <el-form-item label="标识符" prop="identifier">
                <el-input
                  v-model="modelForm.identifier"
                  size="small"
                  auto-complete="off"
                ></el-input>
              </el-form-item>
              <el-form-item label="输入参数">
                <ModelParams
                  :modelParams="modelForm.raw.inputData"
                ></ModelParams>
              </el-form-item>
              <el-form-item label="输出参数">
                <ModelParams
                  :modelParams="modelForm.raw.outputData"
                ></ModelParams>
              </el-form-item>
            </div>
          </div>
          <div v-if="isSelectType('event')">
            <div>
              <el-form-item label="名称" prop="name">
                <el-input
                  v-model="modelForm.name"
                  size="small"
                  auto-complete="off"
                ></el-input>
              </el-form-item>
              <el-form-item label="标识符" prop="identifier">
                <el-input
                  v-model="modelForm.identifier"
                  size="small"
                  auto-complete="off"
                ></el-input>
              </el-form-item>
              <el-form-item label="输出参数">
                <ModelParams
                  :modelParams="modelForm.raw.outputData"
                ></ModelParams>
              </el-form-item>
            </div>
          </div>
          <el-form-item> </el-form-item>
          <el-form-item>
            <el-button @click="cancelEdit">取消</el-button>
            <el-button @click="saveThingModel()" type="primary">保存</el-button>
          </el-form-item>
        </el-form>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>


<script>
import {
  ThingModelSave,
  GetThingModel,
  ParseProperty,
  ProductModelList,
  ProductModelSave,
} from "../../api/productApi";
import { Loading } from "element-ui";
import PropertyModel from "./PropertyModel.vue";
import ModelParams from "./ModelParams.vue";
import vueJsonEditor from "vue-json-editor";
import LuaScriptEditor from "./LuaScriptEditor.vue";
export default {
  name: "ThingModel",
  props: {
    productKey: null,
  },
  data() {
    return {
      loading: false, //是显示加载
      showTab: "functions",
      model: {},
      functions: [],
      formVisible: false,
      modelForm: {},
      enumItems: [{}],
      boolItem: {},
      isAdd: true,
      productModels: [],
      productModelForm: {
        model: "",
        name: "",
        productKey: "",
        script: "",
        type: "",
        state: "dev",
      },
      productModelFormVisible: false,
      scriptRules: {
        model: [
          { required: true, message: "设备型号不能为空", trigger: "blur" },
        ],
        script: [
          { required: true, message: "脚本内容不能为空", trigger: "blur" },
        ],
      },
    };
  },
  // 注册组件
  components: {
    PropertyModel,
    ModelParams,
    vueJsonEditor,
    LuaScriptEditor,
  },
  created() {},
  methods: {
    addFunction() {
      this.formVisible = true;
      this.isAdd = true;
      this.modelForm = {
        type: "property",
        identifier: "",
        name: "",
        raw: {
          name: "",
          identifier: "",
          type: "property",
          dataType: {
            specs: {},
          },
          inputData: [],
          outputData: [],
          enumItems: [],
          boolItem: {
            _true: "",
            _false: "",
          },
        },
      };
    },
    deleteFunction(index, row) {
      if (row.type == "property") {
        let index = this.model.properties.findIndex((p) => {
          return p.identifier == row.identifier;
        });
        this.model.properties.splice(index, 1);
      } else if (row.type == "service") {
        let index = this.model.services.findIndex((s) => {
          return s.identifier == row.identifier;
        });
        this.model.services.splice(index, 1);
      } else if (row.type == "event") {
        let index = this.model.events.findIndex((e) => {
          return e.identifier == row.identifier;
        });
        this.model.events.splice(index, 1);
      }

      this.submitThingModelChange();
    },
    handleEdit(index, row) {
      this.formVisible = true;
      let tmpModel = JSON.parse(JSON.stringify(row));
      if (!tmpModel.raw.dataType) {
        tmpModel.raw.dataType = {};
      }
      tmpModel.raw.inputData = tmpModel.raw.inputData
        ? tmpModel.raw.inputData
        : [];
      tmpModel.raw.outputData = tmpModel.raw.outputData
        ? tmpModel.raw.outputData
        : [];

      let prop = tmpModel.raw;
      if (prop.dataType.type == "enum") {
        let enumSpecs = [];
        for (var p in prop.dataType.specs) {
          enumSpecs.push({
            name: prop.dataType.specs[p],
            value: p,
          });
        }
        this.enumItems = enumSpecs;
      } else if (prop.dataType.type == "bool") {
        this.boolItem = {
          _true: prop.dataType.specs["0"],
          _false: prop.dataType.specs["1"],
        };
      }

      this.modelForm = tmpModel;
      this.isAdd = false;
    },
    cancelEdit() {
      this.formVisible = false;
    },
    isSelectType(type) {
      return type == this.modelForm.type;
    },
    newProperty() {
      return ParseProperty(this.modelForm.raw, this.enumItems, this.boolItem);
    },
    saveThingModel() {
      if (this.isAdd) {
        if (this.modelForm.type == "property") {
          //删除旧的
          const idx = this.model.properties.findIndex(
            (p) => p.identifier == this.modelForm.raw.identifier
          );
          if (idx >= 0) {
            this.model.properties.splice(idx, 1);
          }

          this.model.properties.push(this.newProperty());
        } else if (this.modelForm.type == "service") {
          //删除旧的
          const idx = this.model.services.findIndex(
            (p) => p.identifier == this.modelForm.raw.identifier
          );
          if (idx >= 0) {
            this.model.services.splice(idx, 1);
          }

          this.model.services.push({
            identifier: this.modelForm.identifier,
            name: this.modelForm.name,
            inputData: this.modelForm.raw.inputData,
            outputData: this.modelForm.raw.outputData,
          });
        } else if (this.modelForm.type == "event") {
          //删除旧的
          const idx = this.model.events.findIndex(
            (p) => p.identifier == this.modelForm.raw.identifier
          );
          if (idx >= 0) {
            this.model.events.splice(idx, 1);
          }

          this.model.events.push({
            identifier: this.modelForm.identifier,
            name: this.modelForm.name,
            outputData: this.modelForm.raw.outputData,
          });
        }
      } else {
        if (this.modelForm.type == "property") {
          let prop = this.newProperty();
          for (var i = 0; i < this.model.properties.length; i++) {
            if (this.model.properties[i].identifier == prop.identifier) {
              this.model.properties[i] = prop;
            }
          }
        } else if (this.modelForm.type == "service") {
          this.model.services.forEach((s) => {
            if (s.identifier == this.modelForm.identifier) {
              s.identifier = this.modelForm.identifier;
              s.name = this.modelForm.name;
              s.inputData = this.modelForm.raw.inputData;
              s.outputData = this.modelForm.raw.outputData;
            }
          });
        } else if (this.modelForm.type == "event") {
          this.model.events.forEach((s) => {
            if (s.identifier == this.modelForm.identifier) {
              s.identifier = this.modelForm.identifier;
              s.name = this.modelForm.name;
              s.outputData = this.modelForm.raw.outputData;
            }
          });
        }
      }

      this.submitThingModelChange();
    },
    submitThingModelChange() {
      ThingModelSave({
        productKey: this.productKey,
        model: JSON.stringify(this.model),
      }).then(() => {
        this.getThingModel();
        this.formVisible = false;
      });
    },
    getThingModel() {
      GetThingModel(this.productKey).then((res) => {
        if (!res) {
          res = {};
        }
        res.model = res.model || {
          properties: [],
          events: [],
          services: [],
        };
        res.model.properties = res.model.properties || [];
        res.model.events = res.model.events || [];
        res.model.services = res.model.services || [];
        res.model = JSON.parse(JSON.stringify(res.model));

        this.model = res.model || {};
        let modelFuncs = [];
        this.model.properties.forEach((p) => {
          let params = JSON.stringify(p.dataType.specs || "{}");
          modelFuncs.push({
            raw: p,
            type: "property",
            name: p.name,
            identifier: p.identifier,
            dataTypeName: p.dataType.type,
            params: params == "{}" ? "" : params,
          });
        });
        this.model.events.forEach((e) => {
          let output = {};
          e.outputData.forEach((p) => {
            output[p.identifier] = p.name;
          });
          modelFuncs.push({
            raw: e,
            type: "event",
            name: e.name,
            identifier: e.identifier,
            dataTypeName: "-",
            params: JSON.stringify(output),
          });
        });
        this.model.services.forEach((s) => {
          let input = {};
          (s.inputData || []).forEach((p) => {
            input[p.identifier] = p.name;
          });
          let output = {};
          (s.outputData || []).forEach((p) => {
            output[p.identifier] = p.name;
          });
          modelFuncs.push({
            raw: s,
            type: "service",
            name: s.name,
            identifier: s.identifier,
            dataTypeName: "-",
            params:
              "输入:" +
              JSON.stringify(input) +
              ",输出:" +
              JSON.stringify(output),
          });
        });

        this.functions = modelFuncs;
      });
    },
    tabClick(tab) {
      if (tab.index == "2") {
        this.getProductModels();
      }
    },
    modifyProductModel(row) {
      this.productModelForm = row;
      this.productModelFormVisible = true;
    },
    getProductModels() {
      let loading = Loading.service();
      ProductModelList(this.productKey).then((rst) => {
        this.productModels = rst;
        loading.close();
      });
    },
    addProductModel() {
      this.productModelFormVisible = true;
      this.productModelForm = {
        model: "",
        name: "",
        productKey: "",
        script: "",
        type: "",
        state: "dev",
      };
    },
    cancelProductModel() {
      this.productModelFormVisible = false;
    },
    saveProductModel() {
      this.productModelForm.productKey = this.productKey;
      this.$refs["productModelForm"].validate((valid) => {
        if (valid) {
          this.productModelForm.type = "LuaScript";
          ProductModelSave(this.productModelForm).then(() => {
            this.$notify({
              title: "成功",
              message: "保存成功",
              type: "success",
            });
            this.productModelFormVisible = false;
          });
        }
      });
    },
  },
  watch: {
    immediate: true,
    productKey: function (newVal) {
      if (newVal == "") {
        return;
      }
      this.productKey = newVal;
      this.formVisible = false;
      this.getThingModel();
      this.showTab = "functions";
    },
  },
};
</script>

<style>
.model-form .line {
  text-align: center;
}
.product-script .CodeMirror {
  height: 500px !important;
}
</style>
